/* ****************************************************************** **
**    OpenSees - Open System for Earthquake Engineering Simulation    **
**          Pacific Earthquake Engineering Research Center            **
**                                                                    **
**                                                                    **
** (C) Copyright 1999, The Regents of the University of California    **
** All Rights Reserved.                                               **
**                                                                    **
** Commercial use of this program without express permission of the   **
** University of California, Berkeley, is strictly prohibited.  See   **
** file 'COPYRIGHT'  in main directory for information on usage and   **
** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
**                                                                    **
** Developed by:                                                      **
**   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
**   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
**   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
**                                                                    **
** ****************************************************************** */

// 
// 文件: GPUElementSupport.h
// 创建时间: 2025年9月25日
// 说明: GPU矩阵组装支持的单元类型定义和数据结构
// 作者: OpenSees GPU加速项目组
//

#ifndef GPUElementSupport_h
#define GPUElementSupport_h

#include <cuda_runtime.h>

// GPU支持的材料类型枚举
enum class GPUMaterialType {
    ELASTIC_ISOTROPIC = 0,
    DRUCKER_PRAGER = 1,
    PLASTIC_DAMAGE_CONCRETE_3D = 2,        // 塑性损伤混凝土
    FA_REINFORCED_CONCRETE = 3,             // 钢筋混凝土
    CONCRETE_L01 = 4,                       // ConcreteL01材料
    UNSUPPORTED_MATERIAL = -1
};

// GPU支持的单元类型枚举
// 基于classTags.h中的定义，选取常用单元类型进行GPU加速
enum class GPUSupportedElementType {
    // Truss系列单元
    TRUSS = 12,                    // ELE_TAG_Truss
    TRUSS_SECTION = 13,            // ELE_TAG_TrussSection
    TRUSS2 = 138,                  // ELE_TAG_Truss2

    // 弹性梁2D系列单元
    ELASTIC_BEAM_2D = 3,           // ELE_TAG_ElasticBeam2d
    MOD_ELASTIC_BEAM_2D = 4,       // ELE_TAG_ModElasticBeam2d
    ELASTIC_TIMOSHENKO_BEAM_2D = 145, // ELE_TAG_ElasticTimoshenkoBeam2d

    // 弹性梁3D系列单元
    ELASTIC_BEAM_3D = 5,           // ELE_TAG_ElasticBeam3d
    MOD_ELASTIC_BEAM_3D = 41234,   // ELE_TAG_ModElasticBeam3d
    ELASTIC_TIMOSHENKO_BEAM_3D = 146, // ELE_TAG_ElasticTimoshenkoBeam3d

    // 四边形单元系列
    FOUR_NODE_QUAD = 31,           // ELE_TAG_FourNodeQuad
    FOUR_NODE_QUAD_3D = 32,        // ELE_TAG_FourNodeQuad3d
    FOUR_NODE_QUAD_02 = 134,       // ELE_TAG_FourNodeQuad02

    // 不支持的单元类型
    UNSUPPORTED = -1
};

// GPU单元数据结构
// 设计原则：固定大小数组，避免动态内存分配，便于GPU处理
struct GPUElementData {
    int elementTag;                // 单元标签
    int elementType;               // 单元类型（对应GPUSupportedElementType）
    int materialType;              // 材料类型（对应GPUMaterialType）
    int numNodes;                  // 节点数量
    int numDOF;                    // 总自由度数
    int DOFPerNode;                // 每个节点的自由度数

    // DOF索引映射（最大支持12个节点×6个DOF = 72个DOF）
    int DOFIndices[72];

    // 节点坐标（最大支持12个节点，每个节点3个坐标）
    double nodeCoords[36];         // 12 nodes × 3 coordinates

    // 材料参数（根据材料类型使用不同的参数）
    // ELASTIC_ISOTROPIC: [E, nu]
    // DRUCKER_PRAGER: [E, nu, K, G, sigmaY, rho, alpha, k]
    // PLASTIC_DAMAGE_CONCRETE_3D: [E, nu, ft, fc, beta, Ap, An, Bn]
    // Truss: [E, A, rho]
    // Beam: [E, G, A, Iy, Iz, J, ...]
    // Quad: [E, nu, t, ...]
    double materialProps[32];
    
    // 几何参数（长度、面积、惯性矩等）
    double geometryProps[16];
    
    // 单元状态变量（位移、应变、应力等）
    double stateVariables[32];
    
    // 构造函数：初始化所有成员为0
    __host__ __device__ GPUElementData() {
        elementTag = 0;
        elementType = static_cast<int>(GPUSupportedElementType::UNSUPPORTED);
        materialType = static_cast<int>(GPUMaterialType::UNSUPPORTED_MATERIAL);
        numNodes = 0;
        numDOF = 0;
        DOFPerNode = 0;

        // 初始化所有数组为0
        for (int i = 0; i < 72; i++) DOFIndices[i] = 0;
        for (int i = 0; i < 36; i++) nodeCoords[i] = 0.0;
        for (int i = 0; i < 32; i++) materialProps[i] = 0.0;
        for (int i = 0; i < 16; i++) geometryProps[i] = 0.0;
        for (int i = 0; i < 32; i++) stateVariables[i] = 0.0;
    }
};

// GPU单元特性常量定义
namespace GPUElementConstants {
    // 单元类型特性
    constexpr int MAX_NODES_PER_ELEMENT = 12;      // 最大节点数
    constexpr int MAX_DOF_PER_ELEMENT = 72;        // 最大自由度数（12×6）
    constexpr int MAX_DOF_PER_NODE = 6;            // 每个节点最大自由度数
    constexpr int MAX_MATERIAL_PROPS = 24;         // 最大材料参数数量
    constexpr int MAX_GEOMETRY_PROPS = 16;         // 最大几何参数数量
    constexpr int MAX_STATE_VARIABLES = 32;        // 最大状态变量数量
    
    // Truss单元特性
    constexpr int TRUSS_NODES = 2;                 // Truss单元节点数
    constexpr int TRUSS_DOF_PER_NODE = 3;          // 每个节点DOF数（2D: 2, 3D: 3）
    constexpr int TRUSS_TOTAL_DOF = 6;             // Truss单元总DOF数
    constexpr int TRUSS_MATERIAL_PROPS = 3;        // Truss材料参数数：E, A, rho
    
    // Beam单元特性
    constexpr int BEAM_NODES = 2;                  // Beam单元节点数
    constexpr int BEAM_2D_DOF_PER_NODE = 3;       // 2D梁每个节点DOF数
    constexpr int BEAM_3D_DOF_PER_NODE = 6;       // 3D梁每个节点DOF数
    constexpr int BEAM_2D_TOTAL_DOF = 6;          // 2D梁总DOF数
    constexpr int BEAM_3D_TOTAL_DOF = 12;         // 3D梁总DOF数
    constexpr int BEAM_MATERIAL_PROPS = 8;         // Beam材料参数数：E, G, A, Iy, Iz, J, rho, alpha
    
    // Quad单元特性
    constexpr int QUAD_NODES = 4;                  // Quad单元节点数
    constexpr int QUAD_DOF_PER_NODE = 2;           // 每个节点DOF数（2D平面应力）
    constexpr int QUAD_TOTAL_DOF = 8;             // Quad单元总DOF数
    constexpr int QUAD_MATERIAL_PROPS = 4;         // Quad材料参数数：E, nu, t, rho
    
    // 积分点数量（高斯积分）
    constexpr int TRUSS_INTEGRATION_POINTS = 1;    // Truss单元积分点数
    constexpr int BEAM_INTEGRATION_POINTS = 2;     // Beam单元积分点数
    constexpr int QUAD_INTEGRATION_POINTS = 4;     // Quad单元积分点数（2×2高斯积分）
    
    // 刚度矩阵大小（双精度浮点数数量）
    constexpr int TRUSS_STIFFNESS_SIZE = TRUSS_TOTAL_DOF * TRUSS_TOTAL_DOF;      // 36
    constexpr int BEAM_2D_STIFFNESS_SIZE = BEAM_2D_TOTAL_DOF * BEAM_2D_TOTAL_DOF; // 36  
    constexpr int BEAM_3D_STIFFNESS_SIZE = BEAM_3D_TOTAL_DOF * BEAM_3D_TOTAL_DOF; // 144
    constexpr int QUAD_STIFFNESS_SIZE = QUAD_TOTAL_DOF * QUAD_TOTAL_DOF;         // 64
    
    // 残差向量大小
    constexpr int TRUSS_RESIDUAL_SIZE = TRUSS_TOTAL_DOF;     // 6
    constexpr int BEAM_2D_RESIDUAL_SIZE = BEAM_2D_TOTAL_DOF; // 6
    constexpr int BEAM_3D_RESIDUAL_SIZE = BEAM_3D_TOTAL_DOF; // 12
    constexpr int QUAD_RESIDUAL_SIZE = QUAD_TOTAL_DOF;       // 8
}

// GPU设备函数声明：单元类型检测
__host__ __device__ inline bool isGPUSupported(int elementClassTag) {
    switch (elementClassTag) {
        // Truss系列
        case 12:   // ELE_TAG_Truss
        case 13:   // ELE_TAG_TrussSection
        case 138:  // ELE_TAG_Truss2
        // 弹性梁2D系列
        case 3:    // ELE_TAG_ElasticBeam2d
        case 4:    // ELE_TAG_ModElasticBeam2d
        case 145:  // ELE_TAG_ElasticTimoshenkoBeam2d
        // 弹性梁3D系列
        case 5:    // ELE_TAG_ElasticBeam3d
        case 41234:// ELE_TAG_ModElasticBeam3d
        case 146:  // ELE_TAG_ElasticTimoshenkoBeam3d
        // 四边形单元系列
        case 31:   // ELE_TAG_FourNodeQuad
        case 32:   // ELE_TAG_FourNodeQuad3d
        case 134:  // ELE_TAG_FourNodeQuad02
            return true;
        default:
            return false;
    }
}

// GPU设备函数：获取单元类型枚举
__host__ __device__ inline GPUSupportedElementType getGPUElementType(int elementClassTag) {
    switch (elementClassTag) {
        // Truss系列
        case 12:  return GPUSupportedElementType::TRUSS;
        case 13:  return GPUSupportedElementType::TRUSS_SECTION;
        case 138: return GPUSupportedElementType::TRUSS2;
        // 弹性梁2D系列
        case 3:   return GPUSupportedElementType::ELASTIC_BEAM_2D;
        case 4:   return GPUSupportedElementType::MOD_ELASTIC_BEAM_2D;
        case 145: return GPUSupportedElementType::ELASTIC_TIMOSHENKO_BEAM_2D;
        // 弹性梁3D系列
        case 5:   return GPUSupportedElementType::ELASTIC_BEAM_3D;
        case 41234: return GPUSupportedElementType::MOD_ELASTIC_BEAM_3D;
        case 146: return GPUSupportedElementType::ELASTIC_TIMOSHENKO_BEAM_3D;
        // 四边形单元系列
        case 31:  return GPUSupportedElementType::FOUR_NODE_QUAD;
        case 32:  return GPUSupportedElementType::FOUR_NODE_QUAD_3D;
        case 134: return GPUSupportedElementType::FOUR_NODE_QUAD_02;
        default:  return GPUSupportedElementType::UNSUPPORTED;
    }
}

// GPU设备函数：获取单元节点数
__host__ __device__ inline int getElementNodeCount(GPUSupportedElementType elementType) {
    switch (elementType) {
        case GPUSupportedElementType::TRUSS:
        case GPUSupportedElementType::TRUSS_SECTION:
        case GPUSupportedElementType::TRUSS2:
            return GPUElementConstants::TRUSS_NODES;
            
        case GPUSupportedElementType::ELASTIC_BEAM_2D:
        case GPUSupportedElementType::MOD_ELASTIC_BEAM_2D:
        case GPUSupportedElementType::ELASTIC_TIMOSHENKO_BEAM_2D:
        case GPUSupportedElementType::ELASTIC_BEAM_3D:
        case GPUSupportedElementType::MOD_ELASTIC_BEAM_3D:
        case GPUSupportedElementType::ELASTIC_TIMOSHENKO_BEAM_3D:
            return GPUElementConstants::BEAM_NODES;
            
        case GPUSupportedElementType::FOUR_NODE_QUAD:
        case GPUSupportedElementType::FOUR_NODE_QUAD_3D:
        case GPUSupportedElementType::FOUR_NODE_QUAD_02:
            return GPUElementConstants::QUAD_NODES;
            
        default:
            return 0;
    }
}

// GPU设备函数：获取单元总DOF数
__host__ __device__ inline int getElementDOFCount(GPUSupportedElementType elementType) {
    switch (elementType) {
        case GPUSupportedElementType::TRUSS:
        case GPUSupportedElementType::TRUSS_SECTION:
        case GPUSupportedElementType::TRUSS2:
            return GPUElementConstants::TRUSS_TOTAL_DOF;
            
        case GPUSupportedElementType::ELASTIC_BEAM_2D:
        case GPUSupportedElementType::MOD_ELASTIC_BEAM_2D:
        case GPUSupportedElementType::ELASTIC_TIMOSHENKO_BEAM_2D:
            return GPUElementConstants::BEAM_2D_TOTAL_DOF;
            
        case GPUSupportedElementType::ELASTIC_BEAM_3D:
        case GPUSupportedElementType::MOD_ELASTIC_BEAM_3D:
        case GPUSupportedElementType::ELASTIC_TIMOSHENKO_BEAM_3D:
            return GPUElementConstants::BEAM_3D_TOTAL_DOF;
            
        case GPUSupportedElementType::FOUR_NODE_QUAD:
        case GPUSupportedElementType::FOUR_NODE_QUAD_3D:
        case GPUSupportedElementType::FOUR_NODE_QUAD_02:
            return GPUElementConstants::QUAD_TOTAL_DOF;
            
        default:
            return 0;
    }
}

#endif // GPUElementSupport_h